package mop.controller;

import java.sql.Timestamp;
import java.util.LinkedList;
import java.util.List;

import mop.exception.BusinessRule1Exception;
import mop.exception.BusinessRule3Exception;
import mop.exception.IllegalDependencyException;
import mop.exception.IllegalDescriptionException;
import mop.exception.IllegalDuplicationException;
import mop.exception.IllegalIdException;
import mop.model.World;
import mop.model.project.Project;
import mop.model.project.ProjectInterface;
import mop.model.resource.Resource;
import mop.model.resource.ResourceInterface;
import mop.model.task.Task;
import mop.model.task.TaskInterface;
import mop.model.task.tasktype.TaskType;
import mop.model.task.tasktype.TaskTypeInterface;

/**
 * CreateTaskController
 * 
 * Use case controller for the creation of a new task 
 * (use case 1)
 * 
 * @author	MOP Team 7
 */
public class CreateTaskController extends UseCaseController
{

	
	/**
	 * @see UseCaseController#UseCaseController(World)
	 * 
	 * @effect set the assign task to project controller
	 */
	public CreateTaskController(World world)
	{
		super(world);
		setAssignTTPController(new AssignTaskToProjectController(world));
	}
	
	/**
	 * Return a list with all possible dependencies
	 * TODO relocate source ? -> if so, also do this in modify task details controller
	 * @return a list of interfaces to all tasks in system
	 */
	public List<TaskInterface> getPossibleDependencies()
	{
		return getAllTasks();
	}
	
	/**
	 * Return a list with all possible resources
	 * TODO relocate source ?-> if so, also do this in modify task details controller
	 * @return a list of interfaces to resources
	 */
	public List<ResourceInterface> getPossibleResources()
	{
		return getAllResources();
	}
	
	/**
	 * Return a list of interfaces of all existing tasktypes
	 * 
	 * @return List<TaskType>
	 */
	public List<TaskTypeInterface> getTaskTypes()
	{
		List<TaskType> base = super.getWorld().getTaskTypeDataBase().fetchAll();
		if(base == null) return null;
		
		List<TaskTypeInterface> ret = new LinkedList<TaskTypeInterface>();
		for(TaskType t : base)
		{
			ret.add(t);
		}
		return ret;
	}
	
	/**
	 * CreateTask method
	 * 
	 * @param id			The identifier for the task
	 * @param tt			The tasktypeInterface for the task
	 * @param start			The start time of the task
	 * @param dur			The duration of the task
	 * @param deadline		The deadline of the task
	 * @param dependencies	The dependencies needed by the task
	 * @param resources		The resources to be used by the tasks
	 * 
	 * @throws IllegalIdException
	 * 		| @see convertFromIdToList @see getTaskList
	 * @throws IllegalDependencyException 
	 * 		| @see Task constructor
	 * @throws IllegalDeadlineException 
	 * 		| @see Schedule Constructor
	 * @throws IllegalDuplicationException
	 * 		| @see User#addTask(Task)
	 * @throws BusinessRule1Exception 
	 * 		| @see Schedule#setDates(Timestamp, Timestamp, Timestamp)
	 * @throws BusinessRule3Exception 
	 * 		| @see //TODO: set this to the correct place
	 */
	public TaskInterface createTask(String id,TaskTypeInterface tt,Timestamp start,Timestamp dur,Timestamp deadline,List<String> dependencies,List<String> resources) throws IllegalIdException, IllegalDependencyException, IllegalDuplicationException, BusinessRule3Exception, BusinessRule1Exception
	{
		List<Resource> resourcelist =  getWorld().getResourceDataBase().convertFromIdToList(resources);
		List<Task> tasklist = getTaskList(dependencies);
		TaskType tat = super.getWorld().getTaskTypeDataBase().find(tt.getId());
		Task nt = new Task(id,tat,start,dur,deadline,tasklist,resourcelist,getWorld().getCurrentUser());
		return nt;
	}
	
	/***************************************************************************
	 * 					Assign task to project
	 ***************************************************************************/
	
	/**
	 * @see AssignTaskToProjectController#getProjectList()
	 */
	public List<ProjectInterface> getProjectList()
	{
		return getAssignTTPController().getProjectList();
	}
	
	/**
	 * @see AssignTaskToProjectController#assignTaskToProject(String, String)
	 */
	public void assignTaskToProject(String task, String project) 
		throws IllegalIdException
	{
		getAssignTTPController().assignTaskToProject(task, project);
	}
	
	/**
	 * Set the assign task to project controller
	 * @param controller	assign task to project controller
	 * @post controller is set to given one
	 * 	|getAssignTaskToProjectController() == controller
	 */
	protected void setAssignTTPController(AssignTaskToProjectController controller){
		this.assignTTPController = controller;
	}
	
	/**
	 * Inspector for assignTaskToProjectController
	 * @return assignTTPController
	 */
	protected AssignTaskToProjectController getAssignTTPController(){
		return assignTTPController;
	}
	
	private AssignTaskToProjectController assignTTPController;
	
	/***************************************************************************
	 * 								Visit
	 ***************************************************************************/
	
	/**
	 * Make a CallBack to the visitor
	 * @param v the visitor
	 */
	public void visit(ControllerVisitor v)
	{
		v.action(this);
	}
	
}